using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Diagnostics;


namespace Particle_Tackle
{
    /// <summary>
    /// 基底 Game クラスから派生した、ゲームのメイン クラスです。
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        double beforeTime;
        const string Title = "Particle_Tackle";
        SpriteFont spriteFont;

        //テスト
        Model model;
        float scale;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            beforeTime = 0.0;
            scale = 1.0f;
        }

        /// <summary>
        /// ゲームが実行を開始する前に必要な初期化を行います。
        /// ここで、必要なサービスを照会して、関連するグラフィック以外のコンテンツを
        /// 読み込むことができます。base.Initialize を呼び出すと、使用するすべての
        /// コンポーネントが列挙されるとともに、初期化されます。
        /// </summary>
        protected override void Initialize()
        {
            // TODO: ここに初期化ロジックを追加します。
            GameController.Init();

            model = Content.Load<Model>("a_motion");
            spriteFont = Content.Load<SpriteFont>("Font/Font");

            base.Initialize();
        }

        /// <summary>
        /// LoadContent はゲームごとに 1 回呼び出され、ここですべてのコンテンツを
        /// 読み込みます。
        /// </summary>
        protected override void LoadContent()
        {
            // 新規の SpriteBatch を作成します。これはテクスチャーの描画に使用できます。
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: this.Content クラスを使用して、ゲームのコンテンツを読み込みます。
        }

        /// <summary>
        /// UnloadContent はゲームごとに 1 回呼び出され、ここですべてのコンテンツを
        /// アンロードします。
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: ここで ContentManager 以外のすべてのコンテンツをアンロードします。
        }

        /// <summary>
        /// ワールドの更新、衝突判定、入力値の取得、オーディオの再生などの
        /// ゲーム ロジックを、実行します。
        /// </summary>
        /// <param name="gameTime">ゲームの瞬間的なタイミング情報</param>
        protected override void Update(GameTime gameTime)
        {
            GameController.Update();
            CustomKeyboard.Update();

            // ゲームの終了条件をチェックします。
            if (GameController.getTrigger(Buttons.Back) || CustomKeyboard.getTrigger(Keys.Escape))
                this.Exit();

            //ポーズ
            if (GameController.getTrigger(Buttons.Start) || CustomKeyboard.getTrigger(Keys.P))
                GameManager.PauseChange();

            if (!GameManager.getPauseStatus())
            {
                if (CustomKeyboard.getPress(Keys.Up) || GameController.getPress(Buttons.DPadUp) || GameController.getPress(Buttons.LeftThumbstickUp)) scale += 0.01f;
                if (CustomKeyboard.getPress(Keys.Down) || GameController.getPress(Buttons.DPadDown) || GameController.getPress(Buttons.LeftThumbstickDown)) scale -= 0.01f;
            }

            // TODO: ここにゲームのアップデート ロジックを追加します。
            GameManager.Update();

            base.Update(gameTime);
        }

        /// <summary>
        /// ゲームが自身を描画するためのメソッドです。
        /// </summary>
        /// <param name="gameTime">ゲームの瞬間的なタイミング情報</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: ここに描画コードを追加します。
            GameManager.Draw();

            foreach (ModelMesh mesh in this.model.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.EnableDefaultLighting();

                    effect.View = Matrix.CreateLookAt(
                        new Vector3(100.0f, 100.0f, 100.0f),
                        Vector3.Zero,
                        Vector3.Up
                    );

                    effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                        MathHelper.ToRadians(45.0f),
                        (float)this.GraphicsDevice.Viewport.Width / (float)this.GraphicsDevice.Viewport.Height,
                        1.0f, 1000.0f
                    );

                    effect.World = Matrix.CreateScale(this.scale);
                }
            }

            foreach (ModelMesh mesh in this.model.Meshes)
            {
                mesh.Draw();
            }

            /*spriteBatch.Begin();
            spriteBatch.DrawString(spriteFont, "text sample", new Vector2(0, 0), Color.White);
            spriteBatch.End();*/

            //デバッグ情報表示
            DebugStatus(gameTime);

            base.Draw(gameTime);
        }

        /// <summary>
        /// デバッグ情報表示メソッド（デバッグ時のみ有効）
        /// </summary>
        /// <param name="gameTime"></param>
        [Conditional("DEBUG")]
        private void DebugStatus(GameTime gameTime) {
            //this.Window.Title = Title;
            spriteBatch.Begin();

            ControllerChecker();
            FPS_Counter(gameTime);
            PauseChecker();

            spriteBatch.End();
        }

        /// <summary>
        /// ゲームのFPSをタイトルバーに表示するためのメソッド（デバッグ時のみ有効）
        /// </summary>
        [Conditional("DEBUG")]
        private void FPS_Counter(GameTime gameTime)
        {
            //FPSを格納する変数
            double fps;

            fps = (1000.0f / (gameTime.TotalGameTime.TotalMilliseconds - beforeTime));
            //this.Window.Title = this.Window.Title + " [DEBUG] FPS:" + ((float)fps).ToString();
            spriteBatch.DrawString(spriteFont, "FPS:" + ((float)fps).ToString(), new Vector2(0, 0), Color.White);
            beforeTime = gameTime.TotalGameTime.TotalMilliseconds;
            
        }

        /// <summary>
        /// ポーズ確認（デバッグ時のみ有効）
        /// </summary>
        [Conditional("DEBUG")]
        private void PauseChecker()
        {
            this.Window.Title = "[DEBUG] " + Title;
            if (GameManager.getPauseStatus())
            {
                this.Window.Title = "*" + this.Window.Title;
            }
        }
        
        /// <summary>
        /// コントローラーのチェック
        /// </summary>
        [Conditional("DEBUG")]
        private void ControllerChecker()
        {
            spriteBatch.DrawString(spriteFont, " Left:" + GameController.getLeftStickParamX().ToString(), new Vector2(600, 0), Color.White);
            spriteBatch.DrawString(spriteFont, "      " + GameController.getLeftStickParamY().ToString(), new Vector2(600, 16), Color.White);
            spriteBatch.DrawString(spriteFont, "Right:" + GameController.getRightStickParamX().ToString(), new Vector2(600, 32), Color.White);
            spriteBatch.DrawString(spriteFont, "      " + GameController.getRightStickParamY().ToString(), new Vector2(600, 48), Color.White);
            spriteBatch.DrawString(spriteFont, "    A:" + GameController.getPress(Buttons.A).ToString(), new Vector2(600, 64), Color.White);
            spriteBatch.DrawString(spriteFont, "    B:" + GameController.getPress(Buttons.B).ToString(), new Vector2(600, 80), Color.White);
            spriteBatch.DrawString(spriteFont, "    X:" + GameController.getPress(Buttons.X).ToString(), new Vector2(600, 96), Color.White);
            spriteBatch.DrawString(spriteFont, "    Y:" + GameController.getPress(Buttons.Y).ToString(), new Vector2(600, 112), Color.White);
            spriteBatch.DrawString(spriteFont, "    L:" + GameController.getPress(Buttons.LeftShoulder).ToString(), new Vector2(600, 128), Color.White);
            spriteBatch.DrawString(spriteFont, "    R:" + GameController.getPress(Buttons.RightShoulder).ToString(), new Vector2(600, 144), Color.White);
            spriteBatch.DrawString(spriteFont, "   LT:" + GameController.getLeftTrigger().ToString(), new Vector2(600, 160), Color.White);
            spriteBatch.DrawString(spriteFont, "   RT:" + GameController.getRightTrigger().ToString(), new Vector2(600, 176), Color.White);
            spriteBatch.DrawString(spriteFont, "Start:" + GameController.getPress(Buttons.Start).ToString(), new Vector2(600, 192), Color.White);
            spriteBatch.DrawString(spriteFont, " Back:" + GameController.getPress(Buttons.Back).ToString(), new Vector2(600, 208), Color.White);
        }

    }
}
